import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.Iterator;

import junit.framework.TestCase;

public class LexiconTrieTest extends TestCase
{
	/**
	 * Your test dictionary, containing words in smalltestwords.txt
	 */
	private Scanner words;

	/**
	 * Open smalltestwords.txt and give to the words instance variable. This is automatically run before each test.
	 */
	public void setUp()
	{
		try
		{
			words = new Scanner(new File("smalltestwords.txt"));
		}
		catch (FileNotFoundException e)
		{
			System.out.println(e);
			assertTrue(false);
		}
	}

	/**
	 * Closes smalltestwords.txt after each test.
	 */
	public void tearDown()
	{
		words.close();
	}

	/**
	 * A basic test for the lexicon. You should not assume that passing this test means that your code works.
	 */
	public void testLexicon()
	{
		LexiconTrie l = new LexiconTrie();
		l.load(words);
		
		//l.print();
		
		assertFalse(l.contains(""));
		assertTrue(l.contains("a"));
		assertTrue(l.contains("gorilla"));
		assertTrue(l.contains("gore"));
		assertFalse(l.contains("armin"));
		assertFalse(l.contains("orilla"));
	}

	/**
	 * Further tests for LexiconTrie
	 */
	public void testLexiconFurther()
	{
		LexiconTrie lex = new LexiconTrie();
		Scanner s;
		
		s = new Scanner("wa wb wc"); //separate words with spaces
		lex.load(s);
		assertEquals(lex.toString(), "w[ABC]");
		assertTrue(lex.containsPrefix("w"));
		assertTrue(lex.contains("wa"));
		assertTrue(lex.contains("wb"));
		assertTrue(lex.contains("wc"));
		assertTrue(lex.containsPrefix("wc"));

		s = new Scanner("wawbwc");
		lex.load(s);
		assertEquals(lex.toString(), "w[a[w[b[w[C]]]]]");
		assertTrue(lex.contains("wawbwc"));	
		assertTrue(lex.containsPrefix("wawbwc"));	
		assertTrue(lex.containsPrefix("wa"));
		assertFalse(lex.contains("wa"));
		assertFalse(lex.contains("wb"));
		assertFalse(lex.containsPrefix("wb"));
		
		s = new Scanner("two two three three three");
		lex.load(s);
		assertTrue(lex.contains("two"));
		assertTrue(lex.contains("three"));
		assertTrue(lex.containsPrefix("t"));
		assertTrue(lex.containsPrefix("th"));
		assertTrue(lex.containsPrefix("thr"));
		assertTrue(lex.containsPrefix("thre"));
		assertTrue(lex.containsPrefix("three"));
		assertFalse(lex.containsPrefix("threex"));

		s = new Scanner("it x");
		lex.load(s);
		assertEquals(lex.toString(), "i[T]X"); //printing I[T]X for some reason
		
		s = new Scanner("rat rats ran rack rap run");
		lex.load(s);
		assertEquals(lex.toString(), "r[a[c[K]NPT[S]]u[N]]");
	
		s = new Scanner("rat race ram rim");
		lex.load(s);
		assertEquals(lex.toString(), "r[a[c[E]MT]i[M]]");
	}
	
	/**
	 * Tests LexiconTrie iterator
	 */
	public void testIterator()
	{
		LexiconTrie lex = new LexiconTrie();
		Scanner s;
		
		s = new Scanner("car cat cab cd ca carl d dog dance x xx xxx z zv a aa aaa");
		lex.load(s);
		
		Iterator<String> i = lex.iterator();
		
		assertTrue(i.hasNext());
		assertTrue(i.next().equals("a"));
		assertTrue(i.next().equals("aa"));
		assertTrue(i.next().equals("aaa"));
		assertTrue(i.next().equals("ca"));
		assertTrue(i.next().equals("cab"));
		assertTrue(i.next().equals("car"));
		assertTrue(i.next().equals("carl"));
		assertTrue(i.next().equals("cat"));
		assertTrue(i.next().equals("cd"));
		assertTrue(i.next().equals("d"));
		assertTrue(i.next().equals("dance"));
		assertTrue(i.next().equals("dog"));
		assertTrue(i.next().equals("x"));
		assertTrue(i.next().equals("xx"));
		assertTrue(i.next().equals("xxx"));
		assertTrue(i.next().equals("z"));
		assertTrue(i.next().equals("zv"));
		
		for(int k = 0; k != 10; k++)
			System.out.println(i.next()); //"z", "zv" and "" keep cycling through
		
		// replacing zv with zz makes "z", "zz" cycle constantly
		//i coundn't find any other bad cases
		
		assertFalse(i.hasNext()); //TODO this test not working!!!
	}
}